import json
import logging
import traceback
import uuid
import time
import requests
import datetime
import itertools
from typing import List
from typing import Union
from apis import api_routes
from sqlalchemy import asc
from sqlalchemy import and_
from flask import abort, g, request, jsonify
from security.decoration import certification
from public.sidebar import sidebars
from models.facility.facility import Facility
from models.order.tasks import Tasks
from models.course.course import Course
from models.product.routes import Routes
from models.product.aircraft import Aircraft
from models.course.detailed import Detailed
from models.course.serial import Serial
from public.local import datetime_type, nest, local_time
from models.owner.owner import Owner
from models.owner.entering import Entering
from public.coding import encoding


@api_routes.route("/verify/warning", methods=["POST"])
def func_verify_warning_post_api():
    """
    实时上传设备状态接口
    http://10.1.90.252:8003/api/verify/warning
    Content-Type=application/json
    methods=["POST"]
    {
    "ft_serial":   string      ****    设备编号
    "status_code": int         ****    状态码，1为未运行， 2初始化中， 3为运行中， 4为报警中
    "status_type"  string      status_code==4时， 这个值不为空，报警种类
    "desire":      string      status_code==4时, 这个不为空， 报警信息
    }
    :return:
        {'status': 400, 'msg': '客户端发送请求异常'}
        {'status': 4000, 'msg': "没有查询到设备"}
        {'status': 4001, 'msg': "提交设备状态码错误"}
        {'status': 4004, 'msg': "设备报警状态，报警种类、报警信息不能为空"}
        {'status': 200, "msg": "succeed"}
     ---
    tags:
      - 工控机上传数据
    """
    data: dict = request.get_json()
    ft_serial: Union[str, int, None] = data.get("ft_serial")
    status_code: int = data.get("status_code")
    status_type: str = data.get("status_type")
    desire: Union[str, None] = data.get("desire")

    if ft_serial is None or status_code is None:
        abort(code=400)
    status_code = int(status_code)
    facility: Union[Facility, None] = g.session.query(Facility).filter(Facility.id == ft_serial).first()
    if facility is None:
        return jsonify({'status': 4000, 'msg': "没有查询到设备"})
    if facility.uuid4 is None:
        facility.uuid4 = uuid.uuid4().hex
    if status_code not in [1, 2, 3, 4]:
        return jsonify({'status': 4001, 'msg': "提交设备状态码错误"})

    if status_code == 4 and (status_type is None or desire is None):
        return jsonify({'status': 4004, 'msg': "设备报警状态，报警种类、报警信息不能为空"})
    uuid4key: str = str(facility.uuid4).replace("-", "")
    # uuid4value = g.cache.get(uuid4key)

    temp: dict = {
        "ft_serial": ft_serial,
        "status_code": status_code,
        "status_type": status_type,
        "desire": desire
    }
    allow: dict = {
        1: "1为未运行",
        2: "初始化中",
        3: "为运行中",
        4: "报警中"
    }
    status_value: Union[str, None] = allow.get(status_code)
    if status_value is None:
        status_value = "未知状态"
    g.cache.set(name=uuid4key, value=status_value, ex=40)
    g.cache.set(name="detailed{}".format(uuid4key), value=json.dumps(temp), ex=4)
    return jsonify({'status': 200, "msg": "succeed"})


@api_routes.route("/verify/process", methods=["POST"])
def func_verify_process_post_api():
    """
    数据上传API接口
    http://10.1.90.252:8002/api/verify/process
    Content-Type=application/json
    methods=["POST"]
    {
    "status_code": int       ****   状态码，1==OK， 2==NG, 3==错误，没有加工
    "sequence"     string    ****   产品SN码
    "values":      array[json[key: xxx, value: xxx, floor: xxx, upper: xxx], ...] 上传测试信息, 数据格式如下:
    [{"key": "温度", "value": 23.2, "floor": 1, "upper": 10},  ......]
    }
    :return:
        {'status': 400, 'msg': '客户端发送请求异常'}
        {'status': 4008, 'msg': "上传数据格式错误"}
        {'status': 200, "msg": "succeed"}
     ---
    tags:
      - 工控机上传数据
    """
    data: dict = request.get_json()
    sequence: str = data.get("sequence")
    status_code: int = data.get("status_code")
    values: Union[List[tuple], None] = data.get("values")

    if sequence is None or status_code is None or values is None:
        abort(400)

    if not isinstance(values, list):
        return jsonify({'status': 4008, 'msg': "上传数据格式错误"})
    for value in values:
        if not isinstance(value, dict) or "key" not in list(value.keys()) or "value" not in list(value.keys()):
            return jsonify({'status': 4008, 'msg': "上传数据格式错误"})
        if not isinstance(value, dict) or "floor" not in list(value.keys()) or "upper" not in list(value.keys()):
            return jsonify({'status': 4008, 'msg': "上传数据格式错误"})

    show_array = ["DM8300", "DM8302", "DM8304", "DM8306", "DM8308"]
    write_max_length: int = 5
    start_index: int = 1
    queue_code = "queues{}".format("d8290e0548264bd3a4bd6f42372931f4")

    sava_date: list = []
    for itr_data in values:
        itr_data: dict = itr_data
        sava_date.append({
            "key": itr_data["key"],
            "value": itr_data["value"],
            "floor": itr_data["floor"],
            "upper": itr_data["upper"]
        })
        # noinspection PyBroadException
        try:
            if start_index <= write_max_length:
                float_value = float(itr_data["value"])
                cache_vale = {"address": show_array[start_index - 1], "type": "Float", "value": float_value}
                g.cache.rpush(queue_code, json.dumps(cache_vale))
                g.cache.expire(queue_code, 8)
                start_index = start_index + 1
        except Exception as e:
            traceback.print_exc()

    cache_data: dict = {
        "sequence": sequence,
        "status_code": status_code,
        "sava_date": sava_date
    }
    g.cache.set(name="df17f812943244dca7eda8bd5e7101bd", value=json.dumps(cache_data), ex=60 * 60 * 6)
    return jsonify({'status': 200, "msg": "succeed"})


@api_routes.route("/verify/process", methods=["GET"])
def func_verify_process_get_api():
    """
    验证24号工序是否可以做和机种接口
    http://10.1.90.252:8002/api/verify/process
    Content-Type=application/x-www-form-urlencoded
    methods=["GET"]
    :return:
        {'status': 500, 'msg': '服务器内部出错'}
        {'status': 4000, 'msg': "缓存未读取到产品SN码"}
        {'status': 4001, 'msg': "数据库未读取到产品SN码"}
        {'status': 4002, 'msg': "加工完成，无需重复加工"}
        {'status': 200, "SN": 产品SN, "aircraft": option[1、2 (1==SK151， 2==H77)]}
     ---
    tags:
      - 工控机上传数据
    """
    uuid4value: Union[str, None] = g.cache.get("855e001639b74d8a85912c8999716542")
    if uuid4value is None:
        return jsonify({'status': 4000, 'msg': "缓存未读取到产品SN码"})

    if uuid4value == "样件产品":
        uuid4value2: Union[str, None] = g.cache.get("f58dfa5977f8499188d64ff76a64432f")
        aircraft_name_id: int = 0
        if uuid4value2 is not None and uuid4value2 == "1":
            aircraft_name_id = 1
        elif uuid4value2 is not None and uuid4value2 == "2":
            aircraft_name_id = 2
        return jsonify({'status': 200, "SN": uuid4value, "aircraft": aircraft_name_id})

    db_cs: Union[Course, None] = g.session.query(Course).filter(Course.sequence == uuid4value).first()
    if db_cs is None:
        return jsonify({'status': 4001, 'msg': "数据库未读取到产品SN码"})

    if db_cs.mark == 1:
        return jsonify({'status': 4002, 'msg': "加工完成，无需重复加工"})

    db_aircraft: Aircraft = g.session.query(Aircraft).filter(Aircraft.id == db_cs.aircraft_id).first()
    parm_data: list = db_aircraft.aircraft.split("-")
    aircraft_name_id = int(parm_data[len(parm_data) - 1])

    return jsonify({'status': 200, "SN": uuid4value, "aircraft": aircraft_name_id})


@api_routes.route("/verify/mes/status", methods=["GET"])
def func_verify_mes_status_get_api():
    """
    获取24号工序是否可屏蔽MES以及配方
    http://10.1.90.252:8002/api/verify/mes/status
    Content-Type=application/x-www-form-urlencoded
    methods=["GET"]
    :return:
        {'status': 'status==1为没屏蔽，status==2屏蔽', 'aircraft': '1==SK151, 2==H77'}
     ---
    tags:
      - 工控机上传数据
    """
    status_value: Union[None, str] = g.cache.get(name="f655d33c456b4b51a37ccc27fe6af0f6")
    status_code: int = 2
    if status_value is not None and status_value == "1":
        status_code = 1
    aircraft_cache: Union[None, str] = g.cache.get(name="f58dfa5977f8499188d64ff76a64432f")
    aircraft_code: Union[None, int] = None
    if aircraft_cache is not None and aircraft_cache == "1":
        aircraft_code = 1
    elif aircraft_cache is not None and aircraft_cache == "2":
        aircraft_code = 2

    return jsonify({'status': status_code, 'aircraft': aircraft_code})

